package com.hyacinth.datasource;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceStatLogger;
import com.alibaba.druid.pool.DruidDataSourceStatLoggerImpl;
import com.alibaba.druid.support.logging.Log4jImpl;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Druid连接池数据源
 * @author zhangfb
 * @version 1.0.0.1
 * @since JDK 1.8
 */
public class DataSource4Druid extends BaseDataSource {

    @Override
    public void initDataSource(String driver, String url, String username, String password, int connPollSize) throws SQLException {
        DruidDataSource dataSource = new DruidDataSource();
        //配置连接信息
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);

        // 配置初始化大小、最小、最大
        dataSource.setInitialSize(connPollSize);
        dataSource.setMinIdle(10);
        dataSource.setMaxActive(20);

        // 连接泄漏处理。Druid提供了RemoveAbandonded相关配置，用来关闭长时间不使用的连接（例如忘记关闭连接）
        dataSource.setRemoveAbandoned(true);
        dataSource.setRemoveAbandonedTimeout(180);  //设置检测空连接时长，单位:秒
        dataSource.setLogAbandoned(true); //连接被泄露时是否打印
        // 配置获取连接等待超时的时间,单位：毫秒
        dataSource.setMaxWait(60000);
        // 配置间隔多久才进行一次检测，检测需要关闭的空闲连接，单位:毫秒
        dataSource.setTimeBetweenEvictionRunsMillis(300000);

        // 打开PSCache，并且指定每个连接上PSCache的大小;
        // 如果用Oracle，则把poolPreparedStatements配置为true，mysql可以配置为false。分库分表较多的数据库，建议配置为false
        dataSource.setPoolPreparedStatements(true);
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(20);


        dataSource.setTimeBetweenLogStatsMillis(600000);
        DruidDataSourceStatLogger statLogger = new DruidDataSourceStatLoggerImpl();
        statLogger.setLogger(new Log4jImpl("druid.log"));
        dataSource.setStatLogger(statLogger);// 监控日志输出到文件

        StatFilter statFilter = new StatFilter();
        statFilter.setLogSlowSql(true);
        statFilter.setSlowSqlMillis(5000);

        List<Filter> filters = new ArrayList<Filter>();
        filters.add(statFilter);

        // 配置监控统计拦截的filters, 监控统计："stat",防SQL注入："wall",组合使用： "stat,wall"
        dataSource.setFilters("stat,wall");
        this.dataSource = dataSource;
    }

    @Override
    protected void closeDataSource() {
        DruidDataSource dataSource = (DruidDataSource) this.dataSource;
        dataSource.close();
    }

}
